<template>
  <div 
    :class="[
      'bx-textarea',
      'bx-glass',
      {
        'bx-textarea--disabled': disabled,
        'bx-textarea--readonly': readonly,
        'bx-textarea--error': status === 'error',
        'bx-textarea--warning': status === 'warning',
        'bx-textarea--success': status === 'success',
        [`bx-textarea--${size}`]: size
      }
    ]"
  >
    <textarea
      ref="textareaRef"
      v-model="textareaValue"
      :placeholder="placeholder"
      :disabled="disabled"
      :readonly="readonly"
      :maxlength="maxlength"
      :minlength="minlength"
      :rows="rows"
      :autocomplete="autocomplete"
      :style="textareaStyle"
      class="bx-textarea__inner"
      @focus="handleFocus"
      @blur="handleBlur"
      @input="handleInput"
      @change="handleChange"
      @keydown="handleKeydown"
      @keyup="handleKeyup"
    />
    
    <div 
      v-if="showWordLimit"
      class="bx-textarea__count"
    >
      {{ currentLength }}/{{ maxlength }}
    </div>
  </div>
</template>

<script>
import { ref, computed, nextTick, watch } from 'vue'

export default {
  name: 'BxTextarea',
  props: {
    modelValue: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    rows: {
      type: Number,
      default: 3
    },
    autosize: {
      type: [Boolean, Object],
      default: false
    },
    maxlength: {
      type: Number,
      default: undefined
    },
    minlength: {
      type: Number,
      default: undefined
    },
    showWordLimit: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: 'medium',
      validator: (value) => ['small', 'medium', 'large'].includes(value)
    },
    autocomplete: {
      type: String,
      default: 'off'
    },
    status: {
      type: String,
      default: '',
      validator: (value) => ['', 'error', 'warning', 'success'].includes(value)
    }
  },
  emits: ['update:modelValue', 'focus', 'blur', 'input', 'change', 'keydown', 'keyup'],
  setup(props, { emit }) {
    const textareaRef = ref(null)
    const textareaStyle = ref({})

    const textareaValue = computed({
      get() {
        return props.modelValue
      },
      set(value) {
        emit('update:modelValue', value)
      }
    })

    const currentLength = computed(() => {
      return (props.modelValue || '').length
    })

    const calcTextareaHeight = () => {
      if (!props.autosize || !textareaRef.value) return

      const textarea = textareaRef.value
      
      // 重置高度以获取正确的scrollHeight
      textarea.style.height = 'auto'
      
      let height = textarea.scrollHeight
      
      if (typeof props.autosize === 'object') {
        const { minRows, maxRows } = props.autosize
        const lineHeight = parseInt(getComputedStyle(textarea).lineHeight) || 20
        
        if (minRows) {
          const minHeight = minRows * lineHeight + 16 // 16px for padding
          height = Math.max(height, minHeight)
        }
        
        if (maxRows) {
          const maxHeight = maxRows * lineHeight + 16
          height = Math.min(height, maxHeight)
        }
      }
      
      textareaStyle.value = {
        height: `${height}px`,
        resize: props.autosize ? 'none' : 'vertical'
      }
    }

    const handleFocus = (event) => {
      emit('focus', event)
    }

    const handleBlur = (event) => {
      emit('blur', event)
    }

    const handleInput = (event) => {
      emit('input', event.target.value, event)
      
      if (props.autosize) {
        nextTick(() => {
          calcTextareaHeight()
        })
      }
    }

    const handleChange = (event) => {
      emit('change', event.target.value, event)
    }

    const handleKeydown = (event) => {
      emit('keydown', event)
    }

    const handleKeyup = (event) => {
      emit('keyup', event)
    }

    const focus = () => {
      textareaRef.value?.focus()
    }

    const blur = () => {
      textareaRef.value?.blur()
    }

    // 监听内容变化，自动调整高度
    watch(() => props.modelValue, () => {
      if (props.autosize) {
        nextTick(() => {
          calcTextareaHeight()
        })
      }
    })

    // 初始化高度
    nextTick(() => {
      if (props.autosize) {
        calcTextareaHeight()
      }
    })

    return {
      textareaRef,
      textareaValue,
      textareaStyle,
      currentLength,
      handleFocus,
      handleBlur,
      handleInput,
      handleChange,
      handleKeydown,
      handleKeyup,
      focus,
      blur
    }
  }
}
</script>

<style scoped>
.bx-textarea {
  position: relative;
  display: inline-block;
  width: 100%;
  border-radius: var(--bx-radius-medium);
  border: 1px solid var(--bx-glass-border);
  background: var(--bx-glass-bg);
  backdrop-filter: var(--bx-glass-blur);
  transition: all var(--bx-transition-medium);
  font-family: var(--bx-font-family);
}

.bx-textarea:hover {
  border-color: var(--bx-glass-border-hover);
  background: var(--bx-glass-bg-hover);
}

.bx-textarea:focus-within {
  border-color: rgba(0, 122, 255, 0.5);
  box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.1);
}

.bx-textarea--disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: rgba(255, 255, 255, 0.03);
}

.bx-textarea--readonly {
  background: rgba(255, 255, 255, 0.03);
}

.bx-textarea--error {
  border-color: rgba(255, 59, 48, 0.5);
}

.bx-textarea--error:focus-within {
  box-shadow: 0 0 0 2px rgba(255, 59, 48, 0.1);
}

.bx-textarea--warning {
  border-color: rgba(255, 149, 0, 0.5);
}

.bx-textarea--warning:focus-within {
  box-shadow: 0 0 0 2px rgba(255, 149, 0, 0.1);
}

.bx-textarea--success {
  border-color: rgba(52, 199, 89, 0.5);
}

.bx-textarea--success:focus-within {
  box-shadow: 0 0 0 2px rgba(52, 199, 89, 0.1);
}

.bx-textarea--small {
  font-size: 13px;
}

.bx-textarea--medium {
  font-size: 14px;
}

.bx-textarea--large {
  font-size: 16px;
}

.bx-textarea__inner {
  width: 100%;
  min-height: 80px;
  padding: 12px;
  border: none;
  outline: none;
  background: transparent;
  color: var(--bx-text-primary);
  font-size: inherit;
  font-family: inherit;
  line-height: 1.5;
  resize: vertical;
  box-sizing: border-box;
}

.bx-textarea--small .bx-textarea__inner {
  padding: 8px;
  min-height: 64px;
}

.bx-textarea--large .bx-textarea__inner {
  padding: 16px;
  min-height: 96px;
}

.bx-textarea__inner::placeholder {
  color: var(--bx-text-tertiary);
}

.bx-textarea__inner:disabled {
  cursor: not-allowed;
}

.bx-textarea__count {
  position: absolute;
  bottom: 8px;
  right: 12px;
  color: var(--bx-text-tertiary);
  font-size: 12px;
  line-height: 1;
  background: var(--bx-glass-bg);
  padding: 2px 4px;
  border-radius: var(--bx-radius-small);
  backdrop-filter: var(--bx-glass-blur);
}

.bx-textarea--small .bx-textarea__count {
  bottom: 6px;
  right: 8px;
  font-size: 11px;
}

.bx-textarea--large .bx-textarea__count {
  bottom: 12px;
  right: 16px;
  font-size: 13px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bx-textarea__inner {
    padding: 10px;
    min-height: 72px;
  }
  
  .bx-textarea--small .bx-textarea__inner {
    padding: 8px;
    min-height: 60px;
  }
  
  .bx-textarea--large .bx-textarea__inner {
    padding: 12px;
    min-height: 84px;
  }
  
  .bx-textarea__count {
    font-size: 11px;
  }
}
</style>

